<script lang="ts" setup>
// vue官方文档 为了根据响应式状态自动应用和重新应用副作用，我们可以使用 watchEffect 函数。它立即执行传入的一个函数，同时响应式追踪其依赖，并在其依赖变更时重新运行该函数。
// 可以看出 watchEffect函数不需要传入一个数据源，只需要传入一个函数，在函数中使用到的响应式数据，vue都会追踪依赖，当数据改变时，watchEffect函数会再次运行，并且watchEffect在页面第一次加载的时候就会运行

// 立即执行传入的一个函数，同时响应式追踪其依赖，并在其依赖变更时重新运行该函数。
import { reactive, ref, watchEffect } from "vue";
let count = ref(0);
let age = ref(10);
//  只要里面的变量发生变化，就会触发整个回调函数
watchEffect(() => {
  console.log("count", count.value);
  console.log("age", age.value);
});

const changeCount = () => {
  count.value++;
};

const changeAge = () => {
  age.value += 2;
};

// 清除副作用    就是在触发监听之前会调用一个函数可以处理你的逻辑例如防抖
let message = ref<string>("")
watchEffect((oninvalidate) => {
    //console.log('message', message.value);
    oninvalidate(()=>{
        console.log("处理防抖函数");
        
    })
    console.log('message', message.value);
})
const changeMsg = () => {
    message.value += "hi!"
}


// watchEffect 监听对象属性 ---不需要指明监视的那个属性，监视的回调中用到那个属性就监视那个属性
let person = reactive({name:"张三",age: 18})
const changePerson = () => {
    person.age++
}
watchEffect(()=>{
    console.log("person",person);
})
watchEffect(()=>{
    console.log("person.age",person.age);
})
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// 副作用刷新时机 flush 一般使用post
// 	            pre	            sync	                post
// 更新时机	    组件更新前执行	强制效果始终同步触发	组件更新后执行

let message2 = ref<string>('')
watchEffect((oninvalidate) => {
    //console.log('message', message.value);
    oninvalidate(()=>{
 
    })
    console.log('message2', message2.value);
},{
    // onTrigger  可以帮助我们调试 watchEffect
    flush:"post",
    onTrigger () {
        console.log(123123123);
    }
})
const changeMsg2 = () => {
    message2.value += "ha!"
}


//  停止监听如下：
// let person = reactive({name:"123"})
// const stop = watchEffect(() => {
//     console.log();
// })
// stop() // 停止监听
</script>
<template>
  <div>{{ count }}======{{ age }}</div>
  <div>
    <button @click="changeCount()">修改count</button>
    <button @click="changeAge()">修改age</button>
  </div>
  <div>message:{{ message }}=====message2：{{ message2 }}</div>
  <div>
    <button @click="changeMsg()">修改message</button>
    <button @click="changeMsg2()">修改messagemessage2</button>
  </div>
   <div>person:{{ person }}</div>
  <div>
    <button @click="changePerson()">修改person</button>
  </div>
</template>
<!-- 
    watch 和 watchEffect 的区别
    1、watch是惰性的，页面第一次加载时不触发watch函数，只有监听的数据发生变化时，才会触发watch函数
    2、watch可以以数组的形式监听多个参数，如果多个数据同时发生改变，watch只触发一次
    3、watch监听reactive数据时，是以 （）=>a 这个形式，目的是监听数据的getter函数，对于ref定义的数据，可以直接监听
    4、watch可以获取监听的数据的新值和旧值
    5、watchEffect 函数，在页面第一次加载时就会触发，并且会一直监听追踪内部使用的响应式数据，只要追踪的响应式数据发生变化，watchEffect 都会运行
    6、watchEffect 也可以监听多个参数，只是不能监听对象，因为他无法监测对象内部的变化，可能是watchEffect 无法实现深度监听吧（具体原因还不清楚）

 -->